package com.lh7.ledger.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lh7.ledger.dto.LedgerRecordRequest;
import com.lh7.ledger.mapper.LedgerFieldsMapper;
import com.lh7.ledger.mapper.LedgerRecordsMapper;
import com.lh7.ledger.mapper.RecordValuesMapper;
import com.lh7.ledger.mapper.UsersMapper;
import com.lh7.ledger.pojo.LedgerFields;
import com.lh7.ledger.pojo.LedgerRecords;
import com.lh7.ledger.pojo.RecordValues;
import com.lh7.ledger.service.*;
import com.lh7.ledger.utils.LedgerUtils;
import com.lh7.ledger.vo.StructuredTableResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class IComprehensiveServiceImpl implements IComprehensiveService {

    @Autowired
    private LedgerFieldsMapper ledgerFieldsMapper;
    @Autowired
    private LedgerRecordsMapper ledgerRecordsMapper;
    @Autowired
    private RecordValuesMapper recordValuesMapper;

    @Autowired
    private UsersMapper usersMapper;


    @Override
    public StructuredTableResponse buildLedgerTable(Long ledgerId) {
        QueryWrapper<LedgerFields> queryLedgerFields = new QueryWrapper<>();
        queryLedgerFields.eq("ledger_id", ledgerId);

        QueryWrapper<LedgerRecords> queryLedgerRecords = new QueryWrapper<>();
        queryLedgerRecords.eq("ledger_id", ledgerId);

        List<LedgerFields> fields = ledgerFieldsMapper.selectList(queryLedgerFields);
        List<LedgerRecords> records = ledgerRecordsMapper.selectList(queryLedgerRecords);
        List<RecordValues> values = recordValuesMapper.selectByLedgerId(ledgerId);
        Set<Long> userIds = records.stream()
                .map(LedgerRecords::getUserId)
                .collect(Collectors.toSet());


        Map<Long, String> userIdToName = usersMapper.selectByIds(userIds).stream()
                .collect(Collectors.toMap(pojo.Users::getId, pojo.Users::getUsername));


        List<Map<String, Object>> rows = LedgerUtils.buildStructuredLedgerRecords(fields, records, values, userIdToName);

        List<Map<String, String>> columns = fields.stream()
                .map(f -> Map.of("prop", f.getName(), "label", f.getName()))
                .collect(Collectors.toList());

        return new StructuredTableResponse(rows, columns);
    }

    @Override
    public StructuredTableResponse buildLedgerRecord(Long recordId) {
        // 1. 查询记录
        LedgerRecords record = ledgerRecordsMapper.selectById(recordId);
        if (record == null) {
            return new StructuredTableResponse(new ArrayList<>(), new ArrayList<>());
        }

        Long ledgerId = record.getLedgerId();

        // 2. 查询该台账的所有字段
        List<LedgerFields> fields = ledgerFieldsMapper.selectList(
                new QueryWrapper<LedgerFields>().eq("ledger_id", ledgerId)
        );

        // 3. 查询该记录的字段值
        List<RecordValues> values = recordValuesMapper.selectList(
                new QueryWrapper<RecordValues>().eq("record_id", recordId)
        );

        // 4. 查询用户姓名
        Long userId = record.getUserId();
        String userName = usersMapper.selectById(userId).getUsername();

        // 5. 封装 rows
        Map<Long, String> userIdToName = Map.of(userId, userName);
        List<Map<String, Object>> rows = LedgerUtils.buildStructuredLedgerRecords(fields, List.of(record), values, userIdToName);

        // 6. 封装 columns
        List<Map<String, String>> columns = fields.stream()
                .map(f -> Map.of("prop", f.getName(), "label", f.getName()))
                .collect(Collectors.toList());

        return new StructuredTableResponse(rows, columns);
    }

    @Override
    @Transactional
    public int insertRecord(LedgerRecordRequest recordRequest) {
        // 1. 插入一条新记录（record 表）
        LedgerRecords record = new LedgerRecords();
        record.setLedgerId(recordRequest.getLedgerId());
        record.setUserId(recordRequest.getUserId());
        ledgerRecordsMapper.insert(record); // MyBatis Plus 插入后会自动回填 ID

        Long recordId = record.getId(); // 获取生成的 recordId

        // 2. 插入字段值（record_values 表）
        List<RecordValues> values = new ArrayList<>();
        for (Map.Entry<String, LedgerRecordRequest.FieldValue> entry : recordRequest.getFields().entrySet()) {
            LedgerRecordRequest.FieldValue fv = entry.getValue();
            RecordValues rv = new RecordValues();
            rv.setRecordId(recordId);          // 必填：记录 ID
            rv.setFieldId(fv.getFieldId());    // 必填：字段 ID
            rv.setValueString(fv.getValue());  // 必填：字段值
            values.add(rv);
        }


        // 批量插入
        int insertedCount = recordValuesMapper.insertBatch(values);
        if (insertedCount != values.size()) {
            return 0;
        }
        return insertedCount;
    }

    @Override
    @Transactional
    public int updateRecord(LedgerRecordRequest recordRequest) {
        Long recordId = recordRequest.getRecordId();

        QueryWrapper<RecordValues> queryRecordValues = new QueryWrapper<>();
        queryRecordValues.eq("record_id", recordId);

        // 删除旧值
        recordValuesMapper.delete(queryRecordValues);

        // 插入新值
        List<RecordValues> values = new ArrayList<>();
        for (Map.Entry<String, LedgerRecordRequest.FieldValue> entry : recordRequest.getFields().entrySet()) {
            LedgerRecordRequest.FieldValue fv = entry.getValue();
            RecordValues rv = new RecordValues();
            rv.setRecordId(recordId);
            rv.setFieldId(fv.getFieldId());
            rv.setValueString(fv.getValue());
            values.add(rv);
        }

        int insertedCount = recordValuesMapper.insertBatch(values);
        if (insertedCount != values.size()) {
            return 0;
        }

        return insertedCount;
    }

    @Override
    @Transactional
    public int deleteRecord(Long recordId) {
        QueryWrapper<RecordValues> queryRecordValues = new QueryWrapper<>();
        queryRecordValues.eq("record_id", recordId);


        // 1. 先删除 record_values 中的字段值
        recordValuesMapper.delete(queryRecordValues);

        // 2. 再删除 ledger_records 中的主记录
        return ledgerRecordsMapper.deleteById(recordId);
    }
}
